package alkaid.eis.sys.service;

import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.TreeMap;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import alkaid.eis.common.exceptions.EntityMissingException;
import alkaid.eis.sys.core.SysEisException;
import alkaid.eis.sys.entity.Dept;
import alkaid.eis.sys.entity.DeptComparator;
import alkaid.eis.sys.repository.DeptRepository;
import lombok.RequiredArgsConstructor;

/**
 * 部门服务
 * 
 * @author Lucky Yang
 * @since 0.0.1
 */
@Service
@RequiredArgsConstructor
public class DeptService {
    private final DeptRepository deptRepository;

    @Transactional(rollbackFor = Exception.class)
    public Dept save(Long parentId, Dept dept) {
        Optional.ofNullable(parentId).map(id -> this.findById(parentId)).ifPresent(p -> {
            dept.setParent(p);

            int childCount = deptRepository.countChildByParent(p);
            p.setChildCount(childCount + 1);
            deptRepository.save(dept);
        });

        dept.setChildCount(0);
        deptRepository.save(dept);

        return dept;
    }

    @Transactional(rollbackFor = Exception.class)
    public Dept update(Long id, Dept dept) {
        Dept entity = this.findById(id);
        entity.copy(dept);
        return deptRepository.save(entity);

    }

    @Transactional(rollbackFor = Exception.class)
    public void delete(Long deptId) {
        deptRepository.findById(deptId).ifPresent(dept -> {
            if (deptRepository.countChildByParent(dept) > 0) {
                throw new SysEisException("存在下级部门，不能删除");
            }

            deptRepository.delete(dept);

            Dept parent = dept.getParent();
            if (parent != null) {
                parent.setChildCount(parent.getChildCount() - 1);
            }
        });

    }

    public Dept findById(Long id) {
        return deptRepository.findById(id).orElseThrow(EntityMissingException::new);
    }

    /**
     * 获取所有部门全称， key=id, value=全称
     * 
     * @return
     */
    public Map<Long, String> findFullName() {
        List<Dept> allDeptList = deptRepository.findAll();
        // key=id, value=名称
        Map<Long, String> allDeptMap = allDeptList.stream().collect(Collectors.toMap(Dept::getId, Dept::getName));

        // key=id, value=全称
        Map<Long, String> rslt = new TreeMap<>();
        allDeptList.stream()
                // 排序
                .sorted(DeptComparator.PATHID)
                .forEachOrdered(d -> {
                    String value = Stream.of(d.getPathId().split(Dept.PATH_SEP))
                            .map(Long::valueOf)
                            .map(allDeptMap::get)
                            .collect(Collectors.joining(Dept.PATH_SEP));
                    rslt.put(d.getId(), value);
                });

        return rslt;
    }
}
